package com.yiyuwanglu.basecore.dao;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.yiyuwanglu.basecore.page.Page;

public interface MongoDBBaseDao {


	/**
	 * 根据主键id返回对象
	 * 
	 * @param id
	 *            唯一标识
	 * @return T 对象
	 */
	public <T> T findById(Class<T> entityClass, String id);
	/**
	 * 根据查询条件查询
	 * 
	 * @param id
	 *            唯一标识
	 * @return T 对象
	 */
	public <T> List<T> find(Query query,Class<T> entityClass, String collectionName);
	/**
	 * 根据类获取全部的对象列表
	 * 
	 * @param entityClass
	 *            返回类型
	 * @return List<T> 返回对象列表
	 */
	public <T> List<T> findAll(Class<T> entityClass) ;

	/**
	 * 删除一个对象
	 * 
	 * @param obj
	 *            要删除的Mongo对象
	 */
	public void remove(Object obj) ;

	/**
	 * 添加对象
	 * 
	 * @param obj
	 *            要添加的Mongo对象
	 */
	public void add(Object obj) ;
	
	/**
	 * 添加对象
	 * 
	 * @param obj
	 *            要添加的Mongo对象
	 * @param collectionName
	 * 			  集合名称
	 */
	public void add(Object obj,String collectionName);
	
	/**
	 * 添加对象
	 * 
	 * @param map
	 *            要添加的Mongo map
	 */
	public void add(Map<String, Object> map, String collectionName) ;

	/**
	 * 修改对象
	 * 
	 * @param obj
	 *            要修改的Mongo对象
	 */
	public void saveOrUpdate(Object obj) ;
	
	/**
	 * 
	 * @Title: getMongoTemplate
	 * @Description: 获取mongoTemplate 
	 * @param @return   
	 * @return MongoTemplate   
	 * @throws
	 */
	public MongoTemplate getMongoTemplate();
	
	/**
	 * 修改对象
	 * 
	 * @param obj
	 *            要修改的Mongo对象
	 * @param collectionName
	 *            集合名称     
	 */
	public void saveOrUpdate(Object obj,String collectionName);
	
	/**
	 * @param query
	 * 			查询条件
	 * @param update
	 * 			修改对象
	 * @param collectionName
	 * 			集合名词
	 */	
	public void updateMulti(Query query,Update update,String collectionName);

	/**
	 * 查询并分页
	 * 
	 * @param entityClass
	 *            对象类型
	 * @param query
	 *            查询条件
	 * @param page
	 *            分页
	 * @return
	 */
	/*
	public <T> List<T> findByQuery(Class<T> entityClass, Query query, Page page) {
		Long count = this.count(entityClass, query);
		page.setCount(count);
		int pageNumber = page.getCurrent();
		int pageSize = page.getPageCount();
		query.skip((pageNumber - 1) * pageSize).limit(pageSize);
		return this.mongoTemplate.find(query, entityClass);
	}
	 */
	/**
	 * 
	 * @param entityClass
	 *            查询对象
	 * @param query
	 *            查询条件
	 * @return
	 */
	public <T> Long count(Class<T> entityClass, Query query) ;
	
	/**
	 * 
	 * @param collectionName
	 *            集合名称
	 * @param query
	 *            查询条件
	 * @return
	 */
	public <T> Long count(String collectionName, Query query);
	
	/**
	 * 查询并分页
	 * 
	 * @param entityClass
	 *            对象类型
	 * @param query
	 *            查询条件
	 * @param collectionName
	 *            集合名称
	 * @param page
	 *            分页
	 * @return
	 */
	public <T> List<T> findByQuery(Class<T> entityClass, Query query,String collectionName,Page page);
	
	/**
	 * 查询并分页
	 * 
	 * @param entityClass
	 *            对象类型
	 * @param query
	 *            查询条件
	 * @param collectionName
	 *            
	 * @return
	 */
	public <T> List<T> findByQuery(Class<T> entityClass, Query query,String collectionName);
	
	/**
	 * 批量插入
	 * @param entityClass 对象类
	 * @param collection  要插入的对象集合
	 */
	public <T> void addCollection(Class<T> entityClass, Collection<T> collection);

	/**
	 * 统计查询
	 * @param entityClass 对象类
	 * @param collection  要插入的对象集合
	 */
	public <T> GroupByResults<T> group(Criteria criteria,String inputCollectionName,GroupBy groupBy,Class<T> entityClass);
	
	/**
	 * 统计查询 排序 加分页
	 * @param entityClass 对象类
	 * @param collection  要插入的对象集合
	 */
	public <T> AggregationResults<T> aggregate(Aggregation aggregation, String inputCollectionName, Class<T> outputType);
}
